<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Node 第 2 天 | Megasu的笔记</title>
    <meta name="generator" content="VuePress 1.5.4">
    <link rel="icon" href="/heima2020/favicon.ico">
    <meta name="description" content="Megasu的笔记整理">
    <meta name="author" content="Megasu">
    <meta name="Keywords" content="学习网站,前端,分享">
    <link rel="preload" href="/heima2020/assets/css/0.styles.aa663799.css" as="style"><link rel="preload" href="/heima2020/assets/js/app.e2adc9d2.js" as="script"><link rel="preload" href="/heima2020/assets/js/2.7389c9d3.js" as="script"><link rel="preload" href="/heima2020/assets/js/14.cee0fcf8.js" as="script"><link rel="prefetch" href="/heima2020/assets/js/10.8b750e5f.js"><link rel="prefetch" href="/heima2020/assets/js/11.9224f975.js"><link rel="prefetch" href="/heima2020/assets/js/12.3ea117b6.js"><link rel="prefetch" href="/heima2020/assets/js/13.7524b74f.js"><link rel="prefetch" href="/heima2020/assets/js/15.7a4a27f7.js"><link rel="prefetch" href="/heima2020/assets/js/16.947d882b.js"><link rel="prefetch" href="/heima2020/assets/js/17.79d3becb.js"><link rel="prefetch" href="/heima2020/assets/js/18.48208e3a.js"><link rel="prefetch" href="/heima2020/assets/js/19.3d0c49ef.js"><link rel="prefetch" href="/heima2020/assets/js/20.1f6114c8.js"><link rel="prefetch" href="/heima2020/assets/js/21.85e67b4a.js"><link rel="prefetch" href="/heima2020/assets/js/22.ce482f4d.js"><link rel="prefetch" href="/heima2020/assets/js/23.a150bd35.js"><link rel="prefetch" href="/heima2020/assets/js/24.8cd80d5d.js"><link rel="prefetch" href="/heima2020/assets/js/25.0001c7c1.js"><link rel="prefetch" href="/heima2020/assets/js/26.aa4d65a5.js"><link rel="prefetch" href="/heima2020/assets/js/27.baffff1d.js"><link rel="prefetch" href="/heima2020/assets/js/28.20430dcf.js"><link rel="prefetch" href="/heima2020/assets/js/29.7bbc3c04.js"><link rel="prefetch" href="/heima2020/assets/js/3.0076a912.js"><link rel="prefetch" href="/heima2020/assets/js/30.5f74696f.js"><link rel="prefetch" href="/heima2020/assets/js/31.a0bf56d6.js"><link rel="prefetch" href="/heima2020/assets/js/32.dd5a93dd.js"><link rel="prefetch" href="/heima2020/assets/js/33.92de7335.js"><link rel="prefetch" href="/heima2020/assets/js/34.bf468ed6.js"><link rel="prefetch" href="/heima2020/assets/js/35.28502be1.js"><link rel="prefetch" href="/heima2020/assets/js/36.3622a14c.js"><link rel="prefetch" href="/heima2020/assets/js/37.626e17d3.js"><link rel="prefetch" href="/heima2020/assets/js/38.860020b8.js"><link rel="prefetch" href="/heima2020/assets/js/39.c092c283.js"><link rel="prefetch" href="/heima2020/assets/js/4.586af112.js"><link rel="prefetch" href="/heima2020/assets/js/40.a6ba2743.js"><link rel="prefetch" href="/heima2020/assets/js/41.43d70bcd.js"><link rel="prefetch" href="/heima2020/assets/js/42.6486a709.js"><link rel="prefetch" href="/heima2020/assets/js/43.670b256a.js"><link rel="prefetch" href="/heima2020/assets/js/44.eb371480.js"><link rel="prefetch" href="/heima2020/assets/js/45.5b45f11e.js"><link rel="prefetch" href="/heima2020/assets/js/46.bc59be94.js"><link rel="prefetch" href="/heima2020/assets/js/47.ec36fca9.js"><link rel="prefetch" href="/heima2020/assets/js/48.51e80f8f.js"><link rel="prefetch" href="/heima2020/assets/js/5.6eb7e243.js"><link rel="prefetch" href="/heima2020/assets/js/6.1b7d5a6d.js"><link rel="prefetch" href="/heima2020/assets/js/7.f611fe3c.js"><link rel="prefetch" href="/heima2020/assets/js/8.c14cc922.js"><link rel="prefetch" href="/heima2020/assets/js/9.cd5538bb.js">
    <link rel="stylesheet" href="/heima2020/assets/css/0.styles.aa663799.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/heima2020/" class="home-link router-link-active"><!----> <span class="site-name">Megasu的笔记</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/heima2020/" class="nav-link">
  首页
</a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/heima2020/" class="nav-link">
  首页
</a></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><a href="/heima2020/node/day01" class="sidebar-heading clickable open"><span>Node</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/heima2020/node/day01.html" class="sidebar-link">Node 第 1 天</a></li><li><a href="/heima2020/node/day02.html" aria-current="page" class="active sidebar-link">Node 第 2 天</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/heima2020/node/day02.html#node-第-2-天" class="sidebar-link">Node 第 2 天</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/heima2020/node/day02.html#_1-学习目标" class="sidebar-link">1. 学习目标</a></li><li class="sidebar-sub-header"><a href="/heima2020/node/day02.html#_2-http-模块" class="sidebar-link">2. http 模块</a></li><li class="sidebar-sub-header"><a href="/heima2020/node/day02.html#_3-服务器相关的概念" class="sidebar-link">3. 服务器相关的概念</a></li><li class="sidebar-sub-header"><a href="/heima2020/node/day02.html#_4-创建-web-服务器" class="sidebar-link">4. 创建 web 服务器</a></li><li class="sidebar-sub-header"><a href="/heima2020/node/day02.html#_5-根据不同的-url-响应不同的内容" class="sidebar-link">5. 根据不同的 url 响应不同的内容</a></li><li class="sidebar-sub-header"><a href="/heima2020/node/day02.html#_6-时钟-web-服务器案例" class="sidebar-link">6. 时钟 web 服务器案例</a></li><li class="sidebar-sub-header"><a href="/heima2020/node/day02.html#_7-模块化" class="sidebar-link">7. 模块化</a></li><li class="sidebar-sub-header"><a href="/heima2020/node/day02.html#_8-node-中的模块化" class="sidebar-link">8. Node 中的模块化</a></li><li class="sidebar-sub-header"><a href="/heima2020/node/day02.html#_9-包" class="sidebar-link">9. 包</a></li><li class="sidebar-sub-header"><a href="/heima2020/node/day02.html#_10-npm-初体验" class="sidebar-link">10. npm 初体验</a></li></ul></li></ul></li><li><a href="/heima2020/node/day03.html" class="sidebar-link">Node 第 3 天</a></li><li><a href="/heima2020/node/day04.html" class="sidebar-link">Node 第 4 天</a></li><li><a href="/heima2020/node/day05.html" class="sidebar-link">Node 第 5 天</a></li><li><a href="/heima2020/node/day06.html" class="sidebar-link">Node 第 6 天</a></li><li><a href="/heima2020/node/day07.html" class="sidebar-link">Node 第 7 天</a></li><li><a href="/heima2020/node/day08.html" class="sidebar-link">Node 第 8 天</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h2 id="node-第-2-天"><a href="#node-第-2-天" class="header-anchor">#</a> Node 第 2 天</h2> <h3 id="_1-学习目标"><a href="#_1-学习目标" class="header-anchor">#</a> 1. 学习目标</h3> <p>◆ 能够使用 <code>http</code> 模块写一个基本的 <code>web</code> 服务器</p> <p>◆ 能够说出模块化的好处</p> <p>◆ 能够知道 <code>CommonJS</code> 规定了哪些内容</p> <p>◆ 能够说出 <code>Node.js</code> 中模块的三大分类各自是什么</p> <p>◆ 能够使用 <code>npm</code> 管理包</p> <h3 id="_2-http-模块"><a href="#_2-http-模块" class="header-anchor">#</a> 2. <code>http</code> 模块</h3> <h4 id="_2-1-什么是-http-模块"><a href="#_2-1-什么是-http-模块" class="header-anchor">#</a> 2.1 什么是 <code>http</code> 模块</h4> <ol><li><code>http</code> 模块是 <code>Node.js</code> 官方提供的、用来创建 <code>web</code> 服务器的模块。通过 <code>http</code> 模块提供的 <code>http.createServer()</code> 方法，就能方便的把一台普通的电脑，变成一台 <code>Web</code> 服务器，从而对外提供 <code>Web</code> 资源服务</li></ol> <ol start="2"><li>如果要希望使用 <code>http</code> 模块创建 <code>Web</code> 服务器，则需要先导入它</li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> http <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;http&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="_2-2-进一步理解-http-模块的作用"><a href="#_2-2-进一步理解-http-模块的作用" class="header-anchor">#</a> 2.2 进一步理解 <code>http</code> 模块的作用</h4> <ol><li><p>服务器和普通电脑的区别在于，服务器上安装了 <code>web</code> 服务器软件</p> <ul><li>例如：<code>IIS</code>、<code>Apache</code> 等。通过安装这些服务器软件，就能把一台普通的电脑变成一台 web 服务器</li></ul></li></ol> <ol start="2"><li>在 <code>Node.js</code> 中，我们不需要使用 <code>IIS</code>、<code>Apache</code> 等这些第三方 <code>web</code> 服务器软件。因为我们可以基于 <code>Node.js</code> 提供的 <code>http</code> 模块，通过几行简单的代码，就能轻松的手写一个服务器软件，从而对外提供 <code>web</code> 服务</li></ol> <h3 id="_3-服务器相关的概念"><a href="#_3-服务器相关的概念" class="header-anchor">#</a> 3. 服务器相关的概念</h3> <h4 id="_3-1-ip-地址"><a href="#_3-1-ip-地址" class="header-anchor">#</a> 3.1 <code>ip</code> 地址</h4> <ol><li><code>IP 地址</code>就是互联网上每台计算机的唯一地址，因此 <code>IP 地址</code> 具有唯一性</li> <li><code>IP 地址</code> 的格式：通常用“点分十进制”表示成<code>(a.b.c.d)</code>的形式，其中，<code>a,b,c,d</code> 都是 0~255 之间的十进制整数</li></ol> <ul><li>例如：用点分十进表示的 <code>IP</code>地址<code>（192.168.1.1）</code></li></ul> <p><strong>注意事项</strong>：</p> <ol><li><strong>互联网中每台 <code>Web</code> 服务器，都有自己的 <code>IP</code> 地址</strong> - 例如：大家可以在 <code>Windows</code> 的终端中运行 <code>ping www.baidu.com</code> 命令，即可查看到百度服务器的 <code>IP 地址</code> 2. 在开发期间，自己的电脑既是一台服务器，也是一个客户端，为了方便测试，可以在自己的浏览器中输入 <code>127.0.0.1</code> 这个 <code>IP 地址</code>，就能把自己的电脑当做一台服务器进行访问了</li></ol> <h4 id="_3-2-域名和域名服务器"><a href="#_3-2-域名和域名服务器" class="header-anchor">#</a> 3.2 域名和域名服务器</h4> <ol><li>尽管 <code>IP 地址</code> 能够唯一地标记网络上的计算机，但 <code>IP地址</code> 是一长串数字，不直观，而且不便于记忆，于是人们又发明了另一套字符型的地址方案，即所谓的<strong>域名地址(Domain Name)</strong></li></ol> <ol start="2"><li><code>IP地址</code>和 <code>域名</code> 是一一对应的关系，这份对应关系存放在一种叫做域名服务器 <code>(DNS，Domain name server)</code> 的电脑中。使用者只需通过好记的域名访问对应的服务器即可，对应的转换工作由域名服务器实现。因此，<strong>域名服务器就是提供 <code>IP 地址</code> 和域名之间的转换服务的服务器</strong></li></ol> <p><strong>注意事项：</strong></p> <ol><li><p>单纯使用 <code>IP 地址</code>，互联网中的电脑也能够正常工作。但是有了域名的加持，能让互联网的世界变得更加方便</p></li> <li><p>在开发测试期间， <code>127.0.0.1</code> 对应的域名是 <code>localhost</code>，它们都代表我们自己的这台电脑，在使用效果上没有任何区别</p></li></ol> <h4 id="_3-3-端口号"><a href="#_3-3-端口号" class="header-anchor">#</a> 3.3 端口号</h4> <ol><li>在一台电脑中，可以运行成百上千个 <code>web 服务</code></li> <li>每个<code>web 服务</code> 都对应一个唯一的端口号</li> <li>客户端发送过来的网络请求，通过端口号，可以被准确地交给对应的 <code>web 服务</code> 进行处理</li></ol> <img src="/heima2020/assets/img/001 - 端口号.3a4a06e0.png" alt="端口号"> <h3 id="_4-创建-web-服务器"><a href="#_4-创建-web-服务器" class="header-anchor">#</a> 4. 创建 web 服务器</h3> <h4 id="_4-1-实现步骤和核心代码"><a href="#_4-1-实现步骤和核心代码" class="header-anchor">#</a> 4.1 实现步骤和核心代码</h4> <ol><li>导入 <code>http 模块</code></li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> http <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;http&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ol start="2"><li>创建 <code>web</code> 服务器实例</li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 调用 http.createServer() 方法，即可快速创建一个 web 服务器实例</span>

<span class="token keyword">const</span> server <span class="token operator">=</span> http<span class="token punctuation">.</span><span class="token function">createServer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ol start="3"><li>为服务器实例绑定 <code>request</code> 事件</li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 为服务器实例绑定 request 事件，即可监听客户端发送过来的网络请求</span>

<span class="token comment">// 使用服务器实例的 .on() 方法，为服务器绑定一个 request 事件</span>
server<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">&quot;request&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// 只要有客户端来请求我们自己的服务器，就会被触发 request 事件，从而调用这个事件处理程序</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;访问服务器成功&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ol start="4"><li>启动服务器</li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 调用服务器实例的 .listen() 方法，即可启动当前的 web 服务器实例</span>

server<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token number">80</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;running……&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="_4-2-创建基本的服务器"><a href="#_4-2-创建基本的服务器" class="header-anchor">#</a> 4.2 创建基本的服务器</h4> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 1. 导入 http 模块</span>
<span class="token keyword">const</span> http <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;http&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 2. 创建 web 服务器实例</span>
<span class="token keyword">const</span> server <span class="token operator">=</span> http<span class="token punctuation">.</span><span class="token function">createServer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 3. 为服务器实例绑定 request 事件，监听客户端的请求</span>
server<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">&quot;request&quot;</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;访问服务器成功&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 4. 启动服务器</span>
server<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token number">8080</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;running……&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="_4-3-req-请求对象"><a href="#_4-3-req-请求对象" class="header-anchor">#</a> 4.3 <code>req</code> 请求对象</h4> <p>服务器接收到客户端的请求，就会调用通过 <code>server.on()</code> 为服务器绑定的 <strong>request 事件处理程序</strong>，如果想在事件处理程序中，访问与客户端相关的数据和属性，可以使用如下方式：</p> <div class="language-js extra-class"><pre class="language-js"><code>server<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">&quot;request&quot;</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// req 是请求对象，它包含了与客户端相关的数据和属性</span>
  <span class="token comment">// req.url 获取客户端请求的 url 地址</span>
  <span class="token comment">// req.method 获取客户端请求的类型</span>

  <span class="token keyword">const</span> str <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>req<span class="token punctuation">.</span>url<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> -- </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>req<span class="token punctuation">.</span>method<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>

  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="_4-4-res-响应对象"><a href="#_4-4-res-响应对象" class="header-anchor">#</a> 4.4 <code>res</code> 响应对象</h4> <p>在服务器的 request 事件处理程序中，如果想访问与服务器相关的数据和属性，可以使用如下方式</p> <div class="language-js extra-class"><pre class="language-js"><code>server<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">&quot;request&quot;</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// res 是响应对象，它包含了与服务器相关的数据和属性</span>
  <span class="token comment">// 例如：将字符串发送到客户端</span>

  <span class="token keyword">const</span> str <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>req<span class="token punctuation">.</span>url<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> -- </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>req<span class="token punctuation">.</span>method<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>

  <span class="token comment">// res.end() 方法的作用</span>
  <span class="token comment">// 向客户端发送指定的内容，并结束这次请求的处理过程</span>
  res<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="_4-5-解决中文乱码问题"><a href="#_4-5-解决中文乱码问题" class="header-anchor">#</a> 4.5 解决中文乱码问题</h4> <p>当调用 <code>res.end()</code> 方法，向客户端发送中文内容的时候，会出现乱码问题，此时，需要手动设置内容的编码格式</p> <div class="language-js extra-class"><pre class="language-js"><code>server<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">&quot;request&quot;</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 发送包含中文的内容</span>
  <span class="token keyword">const</span> str <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">您请求的 url 地址是：</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>req<span class="token punctuation">.</span>url<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">，请求的 method 类型是：</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>req<span class="token punctuation">.</span>method<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>

  <span class="token comment">// 为了防止中文乱码问题，需要设置响应头，</span>
  res<span class="token punctuation">.</span><span class="token function">setHeader</span><span class="token punctuation">(</span><span class="token string">&quot;Content-Type&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;text/html; charset=utf-8&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 把包含中文的内容返回给客户端</span>
  res<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="_5-根据不同的-url-响应不同的内容"><a href="#_5-根据不同的-url-响应不同的内容" class="header-anchor">#</a> 5. 根据不同的 <code>url</code> 响应不同的内容</h3> <h4 id="_5-1-核心实现步骤"><a href="#_5-1-核心实现步骤" class="header-anchor">#</a> 5.1 核心实现步骤</h4> <ol><li>获取请求的 <code>url</code> 地址</li> <li>设置默认的响应内容为 <code>404 Not found</code></li> <li>判断用户请求的是否为 <code>/</code> 或 <code>/index.html</code> 首页</li> <li>判断用户请求的是否为 <code>/about.html</code> 关于页面</li> <li>设置 <code>Content-Type</code> 响应头，防止中文乱码</li> <li>使用 <code>res.end()</code> 把内容响应给客户端</li></ol> <h4 id="_5-2-动态响应内容"><a href="#_5-2-动态响应内容" class="header-anchor">#</a> 5.2 动态响应内容</h4> <div class="language-js extra-class"><pre class="language-js"><code>server<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">&quot;request&quot;</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 1、获取请求的 url 地址</span>
  <span class="token keyword">const</span> url <span class="token operator">=</span> req<span class="token punctuation">.</span>url<span class="token punctuation">;</span>
  <span class="token comment">// 2、设置默认的内容为 404 Not Found</span>
  <span class="token keyword">let</span> content <span class="token operator">=</span> <span class="token string">&quot;&lt;h4&gt;404 Not Found&lt;/h4&gt;&quot;</span><span class="token punctuation">;</span>
  <span class="token comment">// 3、用户请求的是首页</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>url <span class="token operator">===</span> <span class="token string">&quot;/&quot;</span> <span class="token operator">||</span> url <span class="token operator">===</span> <span class="token string">&quot;/index.html&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    content <span class="token operator">=</span> <span class="token string">&quot;&lt;h4&gt;首页&lt;/h4&gt;&quot;</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>url <span class="token operator">===</span> <span class="token string">&quot;/about.html&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 4、用户请求的是关于我们页面</span>
    content <span class="token operator">=</span> <span class="token string">&quot;&lt;h4&gt;关于我们&lt;/h4&gt;&quot;</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>

  <span class="token comment">// 5、设置 Content-Type 响应头，防止中文乱码</span>
  res<span class="token punctuation">.</span><span class="token function">setHeader</span><span class="token punctuation">(</span><span class="token string">&quot;Content-Type&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;text/html; charset=utf-8&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 6、将内容发送给客户端</span>
  res<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="_6-时钟-web-服务器案例"><a href="#_6-时钟-web-服务器案例" class="header-anchor">#</a> 6. 时钟 <code>web</code> 服务器案例</h3> <h4 id="_6-1-核心思路"><a href="#_6-1-核心思路" class="header-anchor">#</a> 6.1 核心思路</h4> <p>把文件的实际存放路径，作为每个资源的请求 <code>url 地址</code></p> <img src="/heima2020/assets/img/002 - 核心思路分析.f23771be.png"> <h4 id="_6-2-实现思路"><a href="#_6-2-实现思路" class="header-anchor">#</a> 6.2 实现思路</h4> <ol><li>导入需要的模块</li> <li>创建基本的 <code>web</code> 服务器</li> <li>将资源的请求 <code>url 地址</code> 映射为文件的存放路径</li> <li>读取文件内容并响应给客户端</li> <li>优化资源的请求路径</li></ol> <h4 id="_6-3-实现步骤"><a href="#_6-3-实现步骤" class="header-anchor">#</a> 6.3 实现步骤</h4> <ol><li>导入需要的模块</li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 1.1 导入 http 模块</span>
<span class="token keyword">const</span> http <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;http&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 1.2 导入 fs 文件系统模块</span>
<span class="token keyword">const</span> fs <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;fs&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 1.3 导入 path 路径处理模块</span>
<span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;path&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ol start="2"><li>创建基本的 web 服务器</li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 2.1 创建 web 服务器</span>
<span class="token keyword">const</span> server <span class="token operator">=</span> http<span class="token punctuation">.</span><span class="token function">createServer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 2.2 监听 web 服务器的 request 事件</span>
server<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">&quot;request&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 2.3 启动 web 服务器</span>
server<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token number">80</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;running……&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ol start="3"><li>将资源的请求 <code>url</code> 地址映射为文件的存放路径</li></ol> <div class="language-js extra-class"><pre class="language-js"><code>server<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">&quot;request&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// 3.1 获取到客户端请求的 url 地址</span>
  <span class="token keyword">const</span> url <span class="token operator">=</span> req<span class="token punctuation">.</span>url<span class="token punctuation">;</span>
  <span class="token comment">// 3.2 把请求的 url 地址，映射为本地文件的存放路径</span>
  <span class="token keyword">const</span> fpath <span class="token operator">=</span> path<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> url<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ol start="4"><li>根据映射过来的文件路径读取文件</li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 4.1 根据映射过来的文件路径读取文件</span>
fs<span class="token punctuation">.</span><span class="token function">readFile</span><span class="token punctuation">(</span>fpath<span class="token punctuation">,</span> <span class="token string">&quot;utf8&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">err<span class="token punctuation">,</span> dataStr</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// 4.2 读取文件失败后，向客户端响应固定的 &quot;错误消息&quot;</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> res<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token string">&quot;404 Not Fount&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 4.3 读取文件成功后，将 &quot;读取成功的内容&quot; 响应给客户端</span>
  res<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span>dataStr<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ol start="5"><li>优化资源的请求路径</li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// // 3.2 把请求的 url 地址，映射为本地文件的存放路径</span>
<span class="token comment">// const fpath = path.join(__dirname, url)</span>

<span class="token comment">// 5.1 预定义空白的文件存放路径</span>
<span class="token keyword">let</span> fpath <span class="token operator">=</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>url <span class="token operator">===</span> <span class="token string">&quot;/&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 5.2 如果请求的路径是 / ，则手动指定文件的存放路径</span>
  fpath <span class="token operator">=</span> path<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">&quot;./clock/index.html&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
  <span class="token comment">// 5.3 如果请求的路径不为 / ，则动态拼接文件的存放路径</span>
  fpath <span class="token operator">=</span> path<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">&quot;./clock&quot;</span><span class="token punctuation">,</span> url<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="_7-模块化"><a href="#_7-模块化" class="header-anchor">#</a> 7. 模块化</h3> <h4 id="_7-1-什么是模块化"><a href="#_7-1-什么是模块化" class="header-anchor">#</a> 7.1 什么是模块化</h4> <ol><li><p>模块化是指解决一个复杂问题时，自顶向下逐层<strong>把系统划分成若干模块的过程</strong>。对于整个系统来说，<strong>模块是可组合、分解和更换的单元</strong></p></li> <li><p>编程领域中的模块化，就是<strong>遵守固定的规则</strong>，把一个<strong>大文件</strong>拆成<strong>独立并互相依赖的多个小模块</strong></p></li> <li><p>把代码进行模块化拆分的好处</p></li></ol> <ul><li>提高了代码的复用性</li> <li>提高了代码的可维护性</li> <li>可以实现按需加载</li></ul> <h4 id="_7-2-模块化相关的概念"><a href="#_7-2-模块化相关的概念" class="header-anchor">#</a> 7.2 模块化相关的概念</h4> <ol><li>模块化规范就是对代码进行模块化的拆分与组合时，需要遵守的那些规则，例如：</li></ol> <ul><li>使用什么样的语法格式来引用模块</li> <li>在模块中使用什么样的语法格式向外暴露成员</li></ul> <ol start="2"><li>模块化规范的好处：大家都遵守同样的模块化规范写代码，降低了沟通的成本，极大方便了各个模块之间的相互调用，利人利己</li></ol> <h3 id="_8-node-中的模块化"><a href="#_8-node-中的模块化" class="header-anchor">#</a> 8. <code>Node</code> 中的模块化</h3> <h4 id="_8-1-了解-node-中模块的-3-个大类"><a href="#_8-1-了解-node-中模块的-3-个大类" class="header-anchor">#</a> 8.1 了解 <code>Node</code> 中模块的 3 个大类</h4> <p><code>Node.js</code> 中根据模块来源的不同，将模块分为了 3 大类，分别是：</p> <ol><li>内置模块（内置模块是由 <code>Node.js</code> 官方提供的，例如 <code>fs</code>、<code>path</code>、<code>http</code> 等）</li> <li>自定义模块（用户创建的每个 <code>.js</code> 文件，都是自定 义模块）</li> <li>第三方模块（由第三方开发出来的模块，并非官方提供的内置模块，也不是用户创建的自定义模块，<strong>使用前需要先下载</strong>）</li></ol> <h4 id="_8-2-使用-require-方法加载模块"><a href="#_8-2-使用-require-方法加载模块" class="header-anchor">#</a> 8.2 使用 <code>require</code> 方法加载模块</h4> <p>使用强大的 <code>require()</code> 方法，可以加载需要的<strong>内置模块</strong>、<strong>用户自定义模块</strong>、<strong>第三方模块</strong>进行使用。例如：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 1. 加载内置的 fs 模块</span>
<span class="token keyword">const</span> fs <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;fs&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 2. 加载用户的自定义模块</span>
<span class="token keyword">const</span> custom <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;./custom.js&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 3. 加载第三方模块，(使用第三方模块，下面会进行讲解)</span>
<span class="token keyword">const</span> moment <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;moment&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>注意事项 1： 使用 require() 方法加载其他模块时，会执行被加载模块中的代码</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 加载模块.js</span>
<span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;./被加载的模块.js&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 被加载模块.js</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;我会被打印&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>注意事项 2： 在使用 <code>require</code> 加载用户自定义模块期间，可以省略 <code>.js</code> 后缀名</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 加载模块.js</span>
<span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;./被加载的模块&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="_8-3-了解模块作用域的概念以及好处"><a href="#_8-3-了解模块作用域的概念以及好处" class="header-anchor">#</a> 8.3 了解模块作用域的概念以及好处</h4> <h5 id="_8-3-1-什么是模块作用域"><a href="#_8-3-1-什么是模块作用域" class="header-anchor">#</a> 8.3.1 什么是模块作用域</h5> <p>和函数作用域类似，在自定义模块中定义的变量、方法等成员，只能在当前模块内被访问，外部文件是访问不到的，这种模块级别的访问限制，叫做模块作用域</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 被加载的模块.js</span>

<span class="token keyword">const</span> username <span class="token operator">=</span> <span class="token string">&quot;张三&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;说话&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 加载模块.js</span>

<span class="token keyword">const</span> custom <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;./被加载的模块&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h5 id="_8-3-2-模块作用域的好处"><a href="#_8-3-2-模块作用域的好处" class="header-anchor">#</a> 8.3.2 模块作用域的好处</h5> <p>防止了全局变量污染、文件依赖等问题的产生</p> <h4 id="_8-4-module-对象"><a href="#_8-4-module-对象" class="header-anchor">#</a> 8.4 <code>module</code> 对象</h4> <h5 id="_8-4-1-了解-module-对象"><a href="#_8-4-1-了解-module-对象" class="header-anchor">#</a> 8.4.1 了解 <code>module</code> 对象</h5> <p>在每个 <code>.js</code> 自定义模块中都有一个 <code>module</code> 对象，它里面存储了和当前模块有关的信息，打印如下：</p> <img src="/heima2020/assets/img/003 - module.9d63b541.png"> <h5 id="_8-4-2-了解-module-exports-对象的作用"><a href="#_8-4-2-了解-module-exports-对象的作用" class="header-anchor">#</a> 8.4.2 了解 <code>module.exports</code> 对象的作用</h5> <ol><li><p>在自定义模块中，可以使用 <code>module.exports</code> 对象，将模块内的成员共享出去，供外界使用</p></li> <li><p>外界用 <code>require()</code> 方法导入自定义模块时，得到的就是 <code>module.exports</code> 所指向的对象</p></li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 记载模块.js</span>
<span class="token keyword">const</span> mo <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;./被加载的模块&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>mo<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {}</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 被加载的模块.js</span>

<span class="token comment">// 当外界使用 require 导入一个自定义模块的时候，得到的成员，就是模块中，通过 module.exports 指向的那个对象</span>
<span class="token comment">// console.log('我会被加载')</span>
</code></pre></div><h5 id="_8-4-3-使用-module-exports-向外共享成员"><a href="#_8-4-3-使用-module-exports-向外共享成员" class="header-anchor">#</a> 8.4.3 使用 <code>module.exports</code> 向外共享成员</h5> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 加载模块.js</span>
<span class="token keyword">const</span> mo <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;./被加载的模块.js&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>mo<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 被加载的模块.js</span>

<span class="token comment">// 向 module.exports 对象上挂载 username 属性</span>
module<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>username <span class="token operator">=</span> <span class="token string">&quot;zs&quot;</span><span class="token punctuation">;</span>

<span class="token comment">// 向 module.exports 对象上挂载 sayHello 方法</span>
module<span class="token punctuation">.</span>exports<span class="token punctuation">.</span><span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;Hellp&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h5 id="_8-4-4-共享成员时的注意点"><a href="#_8-4-4-共享成员时的注意点" class="header-anchor">#</a> 8.4.4 共享成员时的注意点</h5> <p>使用 <code>require()</code> 方法导入模块时，导入的结果，永远以 <code>module.exports</code> 指向的对象为准</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 加载模块.js</span>
<span class="token keyword">const</span> mo <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;./被加载的模块.js&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>mo<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { username: '小黑', sayHi: [Function: sayHi] }</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 被加载模块.js</span>

<span class="token comment">// 当外界使用 require 导入一个自定义模块的时候，得到的成员，就是模块中，通过 module.exports 指向的那个对象</span>
<span class="token comment">// console.log(module)</span>

<span class="token comment">// 向 module.exports 对象上挂载 username 属性</span>
module<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>username <span class="token operator">=</span> <span class="token string">&quot;zs&quot;</span><span class="token punctuation">;</span>

<span class="token comment">// 向 module.exports 对象上挂载 sayHello 方法</span>
module<span class="token punctuation">.</span>exports<span class="token punctuation">.</span><span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;Hellp&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// 使用 module.exports 指向一个全新的对象</span>
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  username<span class="token operator">:</span> <span class="token string">&quot;小黑&quot;</span><span class="token punctuation">,</span>
  <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;小黑&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="_8-5-exports-对象"><a href="#_8-5-exports-对象" class="header-anchor">#</a> 8.5 <code>exports</code> 对象</h4> <p>由于 <code>module.exports</code> 单词写起来比较复杂，为了简化向外共享成员的代码，<code>Node</code> 提供了 <code>exports</code> 对象。默认情况下，<code>exports</code> 和 <code>module.exports</code> 指向同一个对象。最终共享的结果，还是以 <code>module.exports</code> 指向的对象为准</p> <div class="language-js extra-class"><pre class="language-js"><code>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>exports<span class="token punctuation">)</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>module<span class="token punctuation">.</span>exports<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 默认情况下，`exports` 和 `module.exports` 指向同一个对象</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>exports <span class="token operator">===</span> module<span class="token punctuation">.</span>exports<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 将私有成员共享出去</span>
exports<span class="token punctuation">.</span>username <span class="token operator">=</span> <span class="token string">&quot;zs&quot;</span><span class="token punctuation">;</span>

<span class="token comment">// 直接挂载方法</span>
exports<span class="token punctuation">.</span><span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;Hellp&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="_8-6-exports-和-module-exports-的使用误区"><a href="#_8-6-exports-和-module-exports-的使用误区" class="header-anchor">#</a> 8.6 <code>exports</code> 和 <code>module.exports</code> 的使用误区</h4> <ol><li>时刻谨记，<code>require()</code> 模块时，得到的永远是 <code>module.exports</code> 指向的对象</li> <li><strong>注意：为了防止混乱，建议大家不要在同一个模块中同时使用 <code>exports</code> 和 <code>module.exports</code></strong></li></ol> <div class="language-js extra-class"><pre class="language-js"><code>exports<span class="token punctuation">.</span>username <span class="token operator">=</span> <span class="token string">&quot;Tom&quot;</span><span class="token punctuation">;</span> <span class="token comment">// 不会被打印</span>

module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  gender<span class="token operator">:</span> <span class="token string">&quot;男&quot;</span><span class="token punctuation">,</span>
  age<span class="token operator">:</span> <span class="token number">22</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>username <span class="token operator">=</span> <span class="token string">&quot;Tom&quot;</span><span class="token punctuation">;</span>

<span class="token comment">// 不会被执行</span>
exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  gender<span class="token operator">:</span> <span class="token string">&quot;男&quot;</span><span class="token punctuation">,</span>
  age<span class="token operator">:</span> <span class="token number">22</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 两个都会执行</span>
module<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>username <span class="token operator">=</span> <span class="token string">&quot;Tom&quot;</span><span class="token punctuation">;</span>

exports<span class="token punctuation">.</span>gender <span class="token operator">=</span> <span class="token string">&quot;男&quot;</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 三个都会打印</span>
exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  gender<span class="token operator">:</span> <span class="token string">&quot;男&quot;</span><span class="token punctuation">,</span>
  age<span class="token operator">:</span> <span class="token number">22</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

module<span class="token punctuation">.</span>exports <span class="token operator">=</span> exports<span class="token punctuation">;</span>
module<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>username <span class="token operator">=</span> <span class="token string">&quot;Tom&quot;</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="_8-7-commonjs-模块化规范"><a href="#_8-7-commonjs-模块化规范" class="header-anchor">#</a> 8.7 <code>CommonJS</code> 模块化规范</h4> <ol><li><code>Node.js</code> 遵循了 <code>CommonJS</code> 模块化规范，<code>CommonJS</code>规定了<strong>模块的特性和各模块之间如何相互依赖</strong></li> <li><code>CommonJS</code> 规定：</li></ol> <ul><li>每个模块内部，<code>module</code> 变量代表当前模块</li> <li><code>module</code> 变量是一个对象，它的 <code>exports</code> 属性（即 <code>module.exports</code>）是对外的接口</li> <li>加载某个模块，其实是加载该模块的 <code>module.exports</code> 属性。require() 方法用于加载模块</li></ul> <h3 id="_9-包"><a href="#_9-包" class="header-anchor">#</a> 9. 包</h3> <h4 id="_9-1-什么是包"><a href="#_9-1-什么是包" class="header-anchor">#</a> 9.1 什么是包</h4> <ol><li><code>Node.js</code> 中的第三方模块又叫做包</li></ol> <h4 id="_9-2-包的来源"><a href="#_9-2-包的来源" class="header-anchor">#</a> 9.2 包的来源</h4> <ol><li>不同于 <code>Node.js</code> 中的内置模块与自定义模块，包是由第三方个人或团队开发出来的，免费供所有人使用</li> <li>注意： <code>Node.js</code> 中的包都是免费且开源的，不需要付费即可免费下载使用</li></ol> <h4 id="_9-3-为什么需要包"><a href="#_9-3-为什么需要包" class="header-anchor">#</a> 9.3 为什么需要包</h4> <ol><li>由于 <code>Node.js</code> 的内置模块仅提供了一些底层的 <code>API</code>，导致在基于内置模块进行项目开发的时，效率很低</li> <li>包是基于内置模块封装出来的，提供了更高级、更方便的 <code>API</code>，极大的提高了开发效率</li> <li>包和内置模块之间的关系，类似于 <code>jQuery</code> 和 浏览器内置 <code>API</code> 之间的关系</li></ol> <h4 id="_9-4-从哪里下载包"><a href="#_9-4-从哪里下载包" class="header-anchor">#</a> 9.4 从哪里下载包</h4> <p>在学习和以后的实际开发中，下载包，都是从 <a href="https://www.npmjs.com/" target="_blank" rel="noopener noreferrer">npm<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> 这个网站下载</p> <h4 id="_9-5-如何下载包"><a href="#_9-5-如何下载包" class="header-anchor">#</a> 9.5 如何下载包</h4> <ol><li><p>下载包使用 <code>npm</code> ，全名叫做 <code>Node Package Manager</code>（简称 <code>npm</code> 包管理工具），这个包管理工具随着 <code>Node.js</code> 的安装包一起被安装到了用户的电脑上。</p></li> <li><p>可以在终端中执行 <code>npm -v</code> 命令，来查看自己电脑上所安装的 <code>npm</code> 包管理工具的版本号</p></li></ol> <img src="/heima2020/assets/img/004- npm.025bf58e.png" alt="npm"> <h3 id="_10-npm-初体验"><a href="#_10-npm-初体验" class="header-anchor">#</a> 10. <code>npm</code> 初体验</h3> <h4 id="_10-1-格式化时间的传统做法"><a href="#_10-1-格式化时间的传统做法" class="header-anchor">#</a> 10.1 格式化时间的传统做法</h4> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 格式化时间方法.js</span>

<span class="token comment">// 1. 定义格式化时间的方法</span>
<span class="token keyword">function</span> <span class="token function">dateFormat</span><span class="token punctuation">(</span><span class="token parameter">dtStr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> dt <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>dtStr<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">const</span> y <span class="token operator">=</span> dt<span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> m <span class="token operator">=</span> <span class="token function">padZero</span><span class="token punctuation">(</span>dt<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> d <span class="token operator">=</span> <span class="token function">padZero</span><span class="token punctuation">(</span>dt<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">const</span> hh <span class="token operator">=</span> <span class="token function">padZero</span><span class="token punctuation">(</span>dt<span class="token punctuation">.</span><span class="token function">getHours</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> mm <span class="token operator">=</span> <span class="token function">padZero</span><span class="token punctuation">(</span>dt<span class="token punctuation">.</span><span class="token function">getMinutes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> ss <span class="token operator">=</span> <span class="token function">padZero</span><span class="token punctuation">(</span>dt<span class="token punctuation">.</span><span class="token function">getSeconds</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>y<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>m<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>d<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>hh<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>mm<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>ss<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// 定义补零的函数</span>
<span class="token keyword">function</span> <span class="token function">padZero</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> n <span class="token operator">&gt;</span> <span class="token number">9</span> <span class="token operator">?</span> n <span class="token operator">:</span> <span class="token string">&quot;0&quot;</span> <span class="token operator">+</span> n<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  dateFormat<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 对时间进行格式化.js</span>

<span class="token comment">// 导入自定义的格式化时间的模块</span>
<span class="token keyword">const</span> <span class="token constant">TIME</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;./014 - timeformat&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 调用方法，进行时间的格式化</span>
<span class="token keyword">const</span> dt <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// console.log(dt)</span>
<span class="token keyword">const</span> newDT <span class="token operator">=</span> <span class="token constant">TIME</span><span class="token punctuation">.</span><span class="token function">dateFormat</span><span class="token punctuation">(</span>dt<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>newDT<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="_10-2-使用第三方包对时间进行格式化"><a href="#_10-2-使用第三方包对时间进行格式化" class="header-anchor">#</a> 10.2 使用第三方包对时间进行格式化</h4> <h5 id="_10-2-1-实现思路分析"><a href="#_10-2-1-实现思路分析" class="header-anchor">#</a> 10.2.1 实现思路分析</h5> <ol><li><p>使用 <code>npm</code> 包管理工具，在项目中安装格式化时间的包 <code>moment</code></p></li> <li><p>使用 <code>require()</code> 导入格式化时间的包</p></li> <li><p>参考 <code>moment</code> 的官方 <code>API</code> 文档对时间进行格式化</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 1.moment</span>
<span class="token keyword">const</span> moment <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;moment&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 2.参考 moment 官方 API 文档，调用对应的方法，对时间进行格式化</span>
<span class="token comment">// 2.1 调用 moment() 方法，得到当前的事件</span>
<span class="token comment">// 2.2 针对当前的时间，调用 format() 方法，按照指定的格式进行时间的格式化</span>
<span class="token keyword">const</span> dt <span class="token operator">=</span> <span class="token function">moment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">&quot;YYYY-MM-DD HH:mm:ss&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>dt<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div></li></ol> <h5 id="_10-2-3-npm-install-命令安装包"><a href="#_10-2-3-npm-install-命令安装包" class="header-anchor">#</a> 10.2.3 <code>npm install</code> 命令安装包</h5> <ol><li>如果想在项目中安装指定名称的包，需要运行如下的命令</li></ol> <div class="language-js extra-class"><pre class="language-js"><code>npm install 包的完整名称
</code></pre></div><ol start="2"><li>上述的装包命令，可以简写成如下格式</li></ol> <div class="language-js extra-class"><pre class="language-js"><code>npm i 包的完整名称

npm i moment
</code></pre></div><h5 id="_10-2-4-moment-对时间格式化"><a href="#_10-2-4-moment-对时间格式化" class="header-anchor">#</a> 10.2.4 <code>moment</code> 对时间格式化</h5> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 1.moment</span>
<span class="token keyword">const</span> moment <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;moment&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 2.参考 moment 官方 API 文档，调用对应的方法，对时间进行格式化</span>
<span class="token comment">// 2.1 调用 moment() 方法，得到当前的事件</span>
<span class="token comment">// 2.2 针对当前的时间，调用 format() 方法，按照指定的格式进行时间的格式化</span>
<span class="token keyword">const</span> dt <span class="token operator">=</span> <span class="token function">moment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">&quot;YYYY-MM-DD HH:mm:ss&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>dt<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="_10-3-node-modules-和-pageage-lock-json-的作用"><a href="#_10-3-node-modules-和-pageage-lock-json-的作用" class="header-anchor">#</a> 10.3 <code>node_modules</code> 和 <code>pageage-lock.json</code> 的作用</h4> <p>初次装包完成后，在项目文件夹下多一个叫做 <code>node_modules</code> 的文件夹和 <code>package-lock.json</code> 的配置文件，他们的作用是：</p> <ol><li><code>node_modules</code> 文件夹用来存放所有已安装到项目中的包。<code>require()</code> 导入第三方包时，就是从这个目录中查找并加载包</li> <li><code>package-lock.json</code> 配置文件用来记录 <code>node_modules</code> 目录下的每一个包的下载信息，例如包的名字、版本号、下载地址等</li></ol> <h4 id="_10-4-安装指定版本的包"><a href="#_10-4-安装指定版本的包" class="header-anchor">#</a> 10.4 安装指定版本的包</h4> <p>默认情况下，使用 <code>npm install</code> 命令安装包的时候，会自动安装最新版本的包。如果需要安装指定版本的包，可以在包名之后，通过 <code>@</code>符号指定具体的版本，例如：</p> <div class="language-js extra-class"><pre class="language-js"><code>npm i moment@<span class="token number">2.22</span><span class="token number">.2</span>
</code></pre></div><h4 id="_10-5-包的语义化版本"><a href="#_10-5-包的语义化版本" class="header-anchor">#</a> 10.5 包的语义化版本</h4> <p><code>npm</code> 规定，在项目根目录中，必须提供一个叫做 <code>package.json</code> 的包管理配置文件。用来记录与项目有关的一些配置信息。例如：</p> <ol><li>项目的名称、版本号、描述等</li> <li>项目中都用到了哪些包</li> <li>哪些包只在开发期间会用到</li> <li>那些包在开发和部署时都需要用到</li></ol></div> <footer class="page-edit"><!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/heima2020/node/day01.html" class="prev">
        Node 第 1 天
      </a></span> <span class="next"><a href="/heima2020/node/day03.html">
        Node 第 3 天
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"><!----></div></div>
    <script src="/heima2020/assets/js/app.e2adc9d2.js" defer></script><script src="/heima2020/assets/js/2.7389c9d3.js" defer></script><script src="/heima2020/assets/js/14.cee0fcf8.js" defer></script>
  </body>
</html>
